import gtk
import pango


class FoolishEditorWindow(object):

    KEY_TAB = 65289
    KEY_ENTER = 65293

    KEY_S = 115

    TAB_WIDTH = 4

    def __init__(self):
        self.window = gtk.Window()
        self.window.set_title("Code Window")
        self.sw = gtk.ScrolledWindow()
        self.textbuffer = gtk.TextBuffer()
        self.textview = gtk.TextView(self.textbuffer)
        font = pango.FontDescription("courier")
        self.textview.modify_font(font)
        self.textview.set_size_request(300, 300)
        self.textview.connect("key-press-event", self.on_key)
        self.sw.add(self.textview)
        self.window.add(self.sw)
        self.window.show_all()
        self.textview.grab_focus()
        # Session
        self.filename = None
        self.session = None

    def close(self):
        self.window.destroy()

    def open_file(self, filename):
        self.filename = filename
        try:
            self.textbuffer.set_text(open(filename).read())
        except:
            self.textbuffer.set_text('')
        self.textbuffer.place_cursor(self.textbuffer.get_start_iter())

    def save_file(self):
        if self.filename is not None:
            start = self.textbuffer.get_start_iter()
            end = self.textbuffer.get_end_iter()
            f = file(self.filename, "w")
            f.write(self.textbuffer.get_text(start, end))
            f.close()
            if self.session is not None:
                self.session.emit("edited")

    def on_key(self, textview, event):
        if event.keyval == self.KEY_TAB:
            self.textbuffer.insert_at_cursor(" " * self.TAB_WIDTH)
            return True
        elif event.keyval == self.KEY_ENTER:
            indent = self.get_indent(self.get_current_line_text())
            self.textbuffer.insert_at_cursor("\n" + " " * indent)
            return True
        elif event.keyval == self.KEY_S and event.state & gtk.gdk.CONTROL_MASK:
            self.save_file()
        #else:
        #    print event.keyval, event.state & gtk.gdk.CONTROL_MASK

    def get_current_line_number(self):
        insert = self.textbuffer.get_insert()
        return self.textbuffer.get_iter_at_mark(insert).get_line()

    def get_current_line_text(self):
        return self.get_line_text(self.get_current_line_number())

    def get_line_text(self, lineno):
        start = self.textbuffer.get_iter_at_line(lineno)
        end = self.textbuffer.get_end_iter()
        return self.textbuffer.get_text(start, end).split("\n")[0]

    def get_indent(self, textline):
        for i in xrange(len(textline)):
            if textline[i] != ' ': return i
        return 0


class FoolishEditor(object):

    def __init__(self):
        self.editor = None

    def edit(self, filename, session=None):
        if self.editor is None:
            self.editor = FoolishEditorWindow()
            self.editor.window.connect("destroy", self.on_window_close)
        self.editor.session = session
        self.editor.open_file(filename)

    def end(self):
        """Closes the editor window (if any is active).
        """
        if self.editor is not None:
            self.editor.close()

    def on_window_close(self, window):
        self.editor = None


if __name__ == "__main__":
    editor = FoolishEditorWindow()
    editor.window.connect("destroy", gtk.main_quit)
    editor.open_file("readme.txt")
    gtk.main()
